function getStyle(el, name) {
	if(el.style[name])	return el.style[name];
	else if(el.currentStyle)	return el.currentStyle[name];
	else if(document.defaultView && document.defaultView.getComputedStyle) {
		name = name.replace(/([A-Z])/g, "-$1");
		name = name.toLowerCase();
		var s = document.defaultView.getComputedStyle(el, "");
		return s && s.getPropertyValue(name);
	}
	else return null;
}

function setStyle(el, name, value) {
	var style = "";
	var upperFlag = 0;
	for(var i=0, L=name.length; i<L; i++) {
		if(name.charAt(i) == "-")	upperFlag = 1;
		else
			if(upperFlag != 1)	style = style + name.charAt(i);
			else {
				style = style + name.charAt(i).toUpperCase();
				upperFlag = 0;
			}
	}
	switch(style) {
		case "opacity" :
			if(el.filters)
				el.style.filter = 'alpha(opacity=' + value + ')';
			else
				el.style.opacity = value / 100;
			break;
		default:
			el.style[style] = value;
	}
}

function css(el, style) {
	var old = {};
	for (var i in style){
		old[i] = getStyle(el, i);
		setStyle(el, i, style[i]);
	}
	return old;
}

function height(elem) {
	if(getStyle(elem, 'display') != "none")
		return elem.offsetHeight || parseInt(getStyle(elem, 'height'));

	var old = css(elem, {"display":"", "visibility":"hidden", "position":"absolute"});
	var h = elem.clientHeight || parseInt(getStyle(elem, 'height'));
	css(old);
	return h;
}

function width(elem) {
	if(getStyle(elem, 'display') != "none")
		return elem.offsetWidth || parseInt(getStyle(elem, 'height'));

	var old = css(elem, {"display":"", "visibility":"hidden", "position":"absolute"});
	var h = elem.clientWidth || parseInt(getStyle(elem, 'height'));
	old = css(old);
	return h;
}

function hasClass(elem, classname) {
	return (" " + elem.className + " ").indexOf(" " + classname + " ") != -1;
}

function addClass(elem, classname) {
	if (! hasClass(elem, classname))		elem.className = elem.className + " " + classname;
}

function removeClass(elem, classname) {
	elem.className = (" " + elem.className + " ").replace(" " + classname + " "," ").replace(/^[\s]+|[\s]+$/, "");
}

function hide(el) {
	el._olddisplay = getStyle(el, 'display');
	setStyle(el, 'display', 'none');
}

function show(el) {
	setStyle(el, 'visibility', 'visible');
	setStyle(el, 'display', el._olddisplay && el._olddisplay != "none" ? el._olddisplay : "");
}

function gradient(el, style, from, to, time, tick, fn) {
	time = time || 1000;
	tick = tick || 20;
	fn = fn ||
		function(from ,to, n, step){
			var pattern = (to + "").replace(/[0-9]+/, "####");
			from = parseInt((from + "").match(/[0-9]+/)[0]);
			to = parseInt((to + "").match(/[0-9]+/)[0]);
			return pattern.replace("####", parseInt(from + (to - from) * step / n));
		};
	var total = parseInt(time / tick);
	for (var i=0; i<=total ; i++){
		(function(){
			var value = fn(from, to, total, i);
			setTimeout( function(){ setStyle(el, style, value); }, tick * i );
		})();
	}
}

function fadeIn(el, t) {
	show(el);
	t = t || 1000;
	gradient(el, 'opacity', 0, 100, t);
}

function fadeOut(el, t) {
	show(el);
	t = t || 1000;
	gradient(el, 'opacity', 100, 0, t);
}

function slide(el, direction, t, from, to) {
	direction = direction || "down";
	t = t || 1000;
	var style = 'height';
	switch(direction) {
		case "up":
			from = parseInt(from || height(el)) + "px";
			to = parseInt(to || '0') + "px";
			break;
		case "right":
			from = parseInt(from || '0') + "px";
			to = parseInt(to || width(el)) + "px";
			style = "width";
			break;
		case "left":
			from = parseInt(from || width(el)) + "px";
			to = parseInt(to || '0') + "px";
			style = "width";
			break;
		case "down":
		default:
			from = parseInt(from || '0') + "px";
			to = parseInt(to || height(el) )+ "px";
			break;
	}
	gradient(el, style, from, to, t);
}